#include "sort.h"
#include <algorithm>
#include <gtest/gtest.h>
#include <random>

std::vector<int> generate_random_num(int size, int low = 0, int high = 100) {
  // 创建随机数生成器
  std::random_device rd;  // 获取真正的随机数种子（如果可用）
  std::mt19937 gen(rd()); // 使用Mersenne Twister算法的伪随机数生成器
  std::uniform_int_distribution<> dis(
      low, high); // 定义随机分布范围，生成1到100之间的随机整数

  std::vector<int> numbers;
  size_t vector_size = size; // 定义要生成的随机整数数量

  // 生成随机数并存放到 vector 中
  for (size_t i = 0; i < vector_size; ++i) {
    int random_number = dis(gen);
    numbers.push_back(random_number);
  }
  return numbers;
}

void print_nums(const std::vector<int> &nums, std::string desc) {
  std::cout << desc << " = ";
  std::copy(nums.begin(), nums.end(),
            std::ostream_iterator<int>(std::cout, ", "));
  std::cout << std::endl;
}

// 冒泡排序
TEST(SORT_TEST, BUBBLE_TEST) {
  std::vector<int> nums = generate_random_num(10);
  // compared nums
  std::vector<int> compared_nums(nums.size());
  std::copy(nums.begin(), nums.end(), compared_nums.begin());
  std::sort(compared_nums.begin(), compared_nums.end());

  sort_nums(nums, bubble_sort);
  EXPECT_EQ(nums, compared_nums);
}

// 插入排序
TEST(SORT_TEST, INSERT_TEST) {
  std::vector<int> nums = generate_random_num(10);

  // compared nums
  std::vector<int> compared_nums(nums.size());
  std::copy(nums.begin(), nums.end(), compared_nums.begin());
  std::sort(compared_nums.begin(), compared_nums.end());

  sort_nums(nums, insert_sort);
  EXPECT_EQ(nums, compared_nums);
}
// 希尔排序
TEST(SORT_TEST, SHELL_TEST) {
  std::vector<int> nums = generate_random_num(111);

  // compared nums
  std::vector<int> compared_nums(nums.size());
  std::copy(nums.begin(), nums.end(), compared_nums.begin());
  std::sort(compared_nums.begin(), compared_nums.end());

  sort_nums(nums, shell_sort);
  EXPECT_EQ(nums, compared_nums);
}

// 选择排序
TEST(SORT_TEST, SELECT_TEST) {
  std::vector<int> nums = generate_random_num(10);

  // compared nums
  std::vector<int> compared_nums(nums.size());
  std::copy(nums.begin(), nums.end(), compared_nums.begin());
  std::sort(compared_nums.begin(), compared_nums.end());

  sort_nums(nums, select_sort);
  EXPECT_EQ(nums, compared_nums);
}

// 归并排序
TEST(SORT_TEST, MERGE_TEST) {
  std::vector<int> nums = generate_random_num(10);

  // compared nums
  std::vector<int> compared_nums(nums.size());
  std::copy(nums.begin(), nums.end(), compared_nums.begin());
  std::sort(compared_nums.begin(), compared_nums.end());

  sort_nums(nums, merge_sort);
  EXPECT_EQ(nums, compared_nums);
}

// 快速排序
TEST(SORT_TEST, QUICK_TEST) {
  std::vector<int> nums = generate_random_num(10);

  // compared nums
  std::vector<int> compared_nums(nums.size());
  std::copy(nums.begin(), nums.end(), compared_nums.begin());
  std::sort(compared_nums.begin(), compared_nums.end());

  sort_nums(nums, quick_sort);
  EXPECT_EQ(nums, compared_nums);
}

// 堆排序
TEST(SORT_TEST, HEAP_TEST) {
  std::vector<int> nums = generate_random_num(10);

  // compared nums
  std::vector<int> compared_nums(nums.size());
  std::copy(nums.begin(), nums.end(), compared_nums.begin());
  std::sort(compared_nums.begin(), compared_nums.end());

  sort_nums(nums, heap_sort);
  EXPECT_EQ(nums, compared_nums);
}

// 计数排序
TEST(SORT_TEST, COUNT_TEST) {
  std::vector<int> nums = generate_random_num(10);

  // compared nums
  std::vector<int> compared_nums(nums.size());
  std::copy(nums.begin(), nums.end(), compared_nums.begin());
  std::sort(compared_nums.begin(), compared_nums.end());

  sort_nums(nums, counting_sort);
  EXPECT_EQ(nums, compared_nums);
}

// 桶排序
TEST(SORT_TEST, BUCKET_TEST) {
  std::vector<int> nums = generate_random_num(100);

  // compared nums
  std::vector<int> compared_nums(nums.size());
  std::copy(nums.begin(), nums.end(), compared_nums.begin());
  std::sort(compared_nums.begin(), compared_nums.end());

  sort_nums(nums, bucket_sort);
  EXPECT_EQ(nums, compared_nums);
}

// 基数排序
TEST(SORT_TEST, RADIX_TEST) {
  std::vector<int> nums = generate_random_num(100);

  // compared nums
  std::vector<int> compared_nums(nums.size());
  std::copy(nums.begin(), nums.end(), compared_nums.begin());
  std::sort(compared_nums.begin(), compared_nums.end());

  sort_nums(nums, radix_sort);
  EXPECT_EQ(nums, compared_nums);
}

int main(int argc, char **argv) {
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}